package cn.com.cis.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.cis.domain.Connection;
import cn.com.cis.domain.JobParams;
import cn.com.cis.domain.TemplateParamDef;
import cn.com.cis.domain.XmlJob;
import cn.com.cis.persistence.ConnectionMapper;
import cn.com.cis.persistence.JobParamsMapper;
import cn.com.cis.persistence.TemplateParamDefMapper;
import cn.com.cis.persistence.XmlJobMapper;
import cn.com.cis.utils.DatabaseHelper;

@Service
public class GenerateXmlService {
	
	@Autowired
	private XmlJobMapper xmlJobMapper;
	
	@Autowired
	private JobParamsMapper jobParamsMapper;
	
	@Autowired
	private ConnectionMapper connectionMapper;
	
	@Autowired
	private TemplateParamDefMapper paramDefMapper;
	
	public List<JobParams> selectParamsOfJob(int id) {
		List<JobParams> jobParams = jobParamsMapper.selectParamsOfJob(id);
		
		for(JobParams jobParam : jobParams){
			int paramDefId = jobParam.getParamDefId();
			TemplateParamDef paramDef = paramDefMapper.selectParamDefByParamId(paramDefId);
			if(null != paramDef){
				jobParam.setParamName(paramDef.getParamName());
				jobParam.setParamType(paramDef.getParamType());
			}
		}
		
		return jobParams;
	}

	public String GetJobEtlXml(int jobId){
		
		XmlJob job = xmlJobMapper.selectJobById(jobId);
		
		String scriptTemplate = "";
		if("job".equals(job.getJobType())){  // 标准job从模板继承script
			XmlJob templateJob = xmlJobMapper.selectJobById(job.getCreateFromTemplate());
			scriptTemplate = templateJob.getScript();
		} else {  // 简单job直接获取script
			scriptTemplate = job.getScript();
		}
		
		if(null == scriptTemplate){
			return "";
		}
		
		// 处理connections部分
		scriptTemplate = addDefaultSupportConnections(scriptTemplate, jobId);
		scriptTemplate = replaceReferConnections(scriptTemplate, jobId);
		
		List<JobParams> params = selectParamsOfJob(jobId);
		for (JobParams param : params) {
			if (!"connection".equals(param.getParamType())) {
				// 替换模板中以&开头的变量
				scriptTemplate = scriptTemplate.replaceAll("&" + param.getParamName(), param.getParamValue());
			}
		}
		
		return scriptTemplate;
	}
	
	// 替换参考连接：<connection id="mongo" refer="&mongo_local"/>
	// refer="&mongo_local"    ==>    user="sa" password="sa" url="mongodb://127.0.0.1:27000/test"
	private String replaceReferConnections(String templateScript, int jobId){
		List<JobParams> params = selectParamsOfJob(jobId);
		for (JobParams param : params) {
			if ("connection".equals(param.getParamType())) {
				
				Connection connection = connectionMapper.selectConnection(Integer.parseInt(param.getParamValue()));
				String username = " user=\"" + connection.getUsername() + "\" ";
				String password = " password=\"" + connection.getPassword() + "\" ";
				String url = DatabaseHelper.getUrlUsingParams(connection.getDatabaseType(), connection.getHostIp(), connection.getPort(), connection.getDatabaseName(), connection.getAdditionalParameter());
				String etlUrl = " url=\"" + url + "\" ";
				
				templateScript = templateScript.replaceAll("refer\\s*=\\s*\"&" + param.getParamName() + "\"", username + password + etlUrl);
			}
		}
		
		return templateScript;
	}
	
	// 被关联的connection和支持的非数据库connection(JEXL, Janino)默认添加到脚本中
	private String addDefaultSupportConnections(String templateScript, int jobId){
		
		StringBuffer tmpString = new StringBuffer(templateScript);
		
		int insertPosition = tmpString.indexOf("<etl>") + 5;
		
		List<JobParams> params = selectParamsOfJob(jobId);
		for (JobParams param : params) {
			if ("connection".equals(param.getParamType())) {
				
				Connection connection = connectionMapper.selectConnection(Integer.parseInt(param.getParamValue()));
				String username = " user=\"" + connection.getUsername() + "\" ";
				String password = " password=\"" + connection.getPassword() + "\" ";
				String url = DatabaseHelper.getUrlUsingParams(connection.getDatabaseType(), connection.getHostIp(), connection.getPort(), connection.getDatabaseName(), connection.getAdditionalParameter());
				String etlUrl = " url=\"" + url + "\" ";
				
				tmpString.insert(insertPosition, "\n\t<connection id=\"" + param.getParamName() + "\" "+ username + password + etlUrl + "/>\n");
			}
		}
		
		tmpString.insert(insertPosition, "\n\t<connection id=\"janino\" driver=\"janino\"/>\n");
		
		return tmpString.toString();
	}

}
